package com.changgou.seckill.task;

import com.alibaba.fastjson.JSON;
import com.changgou.common.pojo.SeckillStatus;
import com.changgou.common.util.IdWorker;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.seckill.pojo.SeckillOrder;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class MuilThreadingCreateOrder {
    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 异步执行
     *   @Async：该方法将异步调用（底层多线程调用）
     */
    @Async
    public  void  createOrder(){
        try{
            // 从redis中取用户排队的信息(右取)
            SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundListOps("SeckillOrderQueue").rightPop();
            // 用户排队信息为空
            if (seckillStatus==null){
                return;
            }
            String time =seckillStatus.getTime();
            long id = seckillStatus.getGoodsId();
            String username = seckillStatus.getUsername();
            String namespace = "SeckillGoods_"+time;
            // 先到SeckillGoodsCountList队列中获得该商品的信息，如果能获得，则下单
            Object seckillGoodRedis = redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillStatus.getGoodsId()).rightPop();
           // 没有商品信息
            if (seckillGoodRedis==null){
                 // 则表示没有库存，清理排队信息
                clearUserQueue(username);
                return;
            }

            // 从redis中查询商品数据
            SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps(namespace).get(id);
            // 判断秒杀的库存是否大于0
            if(seckillGoods==null || seckillGoods.getStockCount()<=0){
                throw  new RuntimeException("已售馨");
            }
            // 创建订单对象订单
            SeckillOrder seckillOrder = new SeckillOrder();
            //商品id
            seckillOrder.setSeckillId(id);
            seckillOrder.setId(idWorker.nextId());
            //价格
            seckillOrder.setMoney(seckillGoods.getPrice());
            //用户名
            seckillOrder.setUserId(username);
            //创建订单的时间
            seckillOrder.setCreateTime(new Date());
            //未支付
            seckillOrder.setStatus("0");
            //将订单对象存入到redis中
            redisTemplate.boundHashOps("SeckillOrder").put(username,seckillOrder);
            /**
             * 库存递减
             */
            seckillGoods.setStockCount(seckillGoods.getStockCount()-1);
            //
            Long size = redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillGoods.getId()).size();
            // 商品是最后一件
            if (size<=0){
                // 同步数量
                seckillGoods.setStockCount(size.intValue());
                //同步数据到mysql
                seckillGoodsMapper.updateByPrimaryKey(seckillGoods);
                // 删除redis中该商品的数据
                redisTemplate.boundHashOps(namespace).delete(id);
            }else {
                //更新redis
                redisTemplate.boundHashOps(namespace).put(id,seckillGoods);
            }

            // 更新下单状态
            seckillStatus.setOrderId(seckillOrder.getId());
            seckillStatus.setMoney(Float.valueOf(seckillGoods.getPrice()));
            seckillStatus.setStatus(2);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      System.out.println(simpleDateFormat.format("下单成功"+new Date()));
           // 发送延时队列
            rabbitTemplate.convertAndSend("orderDelaySecillQueue", (Object) JSON.toJSONString(seckillStatus), new MessagePostProcessor() {
                @Override
                public Message postProcessMessage(Message message) throws AmqpException {
                    message.getMessageProperties().setExpiration("10000");
                    return message;
                }
            });
            //存储用户排队的信息
            redisTemplate.boundHashOps("UserQueueStatus").put(username,seckillStatus);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 清理用户的信息(设置超时的时间)
     * @param username
     */
    public  void clearUserQueue(String username){
        // 清理用户的排队次数
        redisTemplate.boundHashOps("userQueueCount").delete(username);
        // 清理用户排队的信息
        redisTemplate.boundHashOps("UserQueueStatus").delete(username);
    }
}
